Skip to content

fix: enhance count argument handling in WebSearchTool to support string input#741

Open
Xeven777 wants to merge 1 commit intosipeed:mainfrom
Xeven777:fix/web-count-type-handling
Open

fix: enhance count argument handling in WebSearchTool to support string input#741
Xeven777 wants to merge 1 commit intosipeed:mainfrom
Xeven777:fix/web-count-type-handling

Conversation

@Xeven777
Copy link

This pull request updates the handling of the count argument in the WebSearchTool.Execute method to make it more robust. The main improvement is that the method can now accept both numeric and string values for the count parameter, converting strings to integers when possible.

Improvements to argument handling:

  • Enhanced the parsing of the count argument in WebSearchTool.Execute to accept both float64 and string types, converting string values to integers using strconv.Atoi and validating the range (1–10).
  • Added the strconv package import in pkg/tools/web.go to support string-to-integer conversion.

Copilot AI review requested due to automatic review settings February 24, 2026 21:06
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request modifies the WebSearchTool.Execute method to handle the count parameter more flexibly by accepting both float64 (from JSON) and string inputs. The changes use a switch statement with type assertions to parse and validate the count parameter, adding string-to-integer conversion via strconv.Atoi and strict integer validation for float64 values using math.Round and math.Abs.

Changes:

  • Replaced simple float64 type assertion with a switch statement handling both float64 and string types
  • Added strict validation to reject fractional float64 values
  • Added string parsing support using strconv.Atoi
  • Imported math and strconv packages

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 478 to 491
switch v := args["count"].(type) {
case float64:
rounded := int(math.Round(v))
if math.Abs(v-float64(rounded)) > 1e-9 {
return ErrorResult(fmt.Sprintf("count must be an integer, got %v", v))
}
if rounded > 0 && rounded <= 10 {
count = rounded
}
case string:
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 10 {
count = n
}
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new count parameter handling logic (both float64 and string cases) lacks test coverage. The existing test file web_test.go has no tests for the count parameter. Consider adding tests for: valid integer values (as float64), fractional values that should be rejected, string inputs (valid and invalid), boundary values (0, 1, 10, 11), and the default fallback behavior when count is omitted or invalid.

Copilot uses AI. Check for mistakes.
Comment on lines +480 to +486
rounded := int(math.Round(v))
if math.Abs(v-float64(rounded)) > 1e-9 {
return ErrorResult(fmt.Sprintf("count must be an integer, got %v", v))
}
if rounded > 0 && rounded <= 10 {
count = rounded
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new validation that rejects fractional float64 values (lines 481-482) is a breaking change from the previous behavior, which silently converted fractional values to integers. If the count parameter receives 5.5, the old code would have converted it to 5 and used it, but the new code returns an error. Consider whether this breaking change is intentional and justified, or if you should maintain backward compatibility by silently truncating/rounding fractional values as the original code did.

Suggested change
rounded := int(math.Round(v))
if math.Abs(v-float64(rounded)) > 1e-9 {
return ErrorResult(fmt.Sprintf("count must be an integer, got %v", v))
}
if rounded > 0 && rounded <= 10 {
count = rounded
}
n := int(v)
if n > 0 && n <= 10 {
count = n
}

Copilot uses AI. Check for mistakes.
"encoding/json"
"fmt"
"io"
"math"
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The math import is only used for the strict integer validation (math.Round and math.Abs). If the fractional value validation is removed (as suggested in other comments), this import would no longer be needed and should be removed to avoid unnecessary dependencies.

Suggested change
"math"

Copilot uses AI. Check for mistakes.
Comment on lines +487 to 490
case string:
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 10 {
count = n
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding string support for the count parameter deviates from the established pattern in the codebase. Other tools with integer parameters (like skills_search.go line 62, cron.go lines 149-150, i2c_linux.go line 159) only accept float64, not strings. The Parameters() method declares count as type "integer", which means LLM APIs will send it as a number (decoded as float64 in Go). Unless there's a specific use case requiring string support (e.g., manual testing, specific provider quirks), consider removing the string case to maintain consistency with other tools in the codebase.

Suggested change
case string:
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 10 {
count = n
}

Copilot uses AI. Check for mistakes.
Comment on lines +480 to +486
rounded := int(math.Round(v))
if math.Abs(v-float64(rounded)) > 1e-9 {
return ErrorResult(fmt.Sprintf("count must be an integer, got %v", v))
}
if rounded > 0 && rounded <= 10 {
count = rounded
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The strict integer validation for float64 values is inconsistent with how other tools in the codebase handle numeric parameters. For example, skills_search.go (line 62-63) and cron.go (line 155, 161) simply cast float64 to int without checking for fractional parts. When JSON is unmarshaled into map[string]any, integer values become float64 by default in Go, so values like 5.0 are expected and valid. The current implementation would reject 5.0000000001 due to floating-point precision issues, which could cause unexpected failures. Consider either removing this validation to match the codebase pattern or at least using int(v) instead of math.Round if you want to be lenient with very small fractional parts.

Suggested change
rounded := int(math.Round(v))
if math.Abs(v-float64(rounded)) > 1e-9 {
return ErrorResult(fmt.Sprintf("count must be an integer, got %v", v))
}
if rounded > 0 && rounded <= 10 {
count = rounded
}
n := int(v)
if n > 0 && n <= 10 {
count = n
}

Copilot uses AI. Check for mistakes.
count = rounded
}
case string:
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 10 {
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the string parsing fails or the value is out of range, the code silently falls back to the default maxResults without informing the user. This is inconsistent with the float64 case (lines 481-482) which returns an error for invalid values. Consider either returning an error for invalid string inputs to maintain consistency, or document why strings are treated more leniently than floats. The silent fallback could confuse users who expect their count parameter to be respected.

Suggested change
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 10 {
n, err := strconv.Atoi(v)
if err != nil {
return ErrorResult(fmt.Sprintf("count must be an integer, got %q", v))
}
if n > 0 && n <= 10 {

Copilot uses AI. Check for mistakes.
@Xeven777
Copy link
Author

@xiaket review ?

Copy link

@nikolasdehor nikolasdehor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean fix for the type-mismatch issue where LLMs send count as a string instead of a number.

Two small things:

  1. The float64 non-integer check feels over-engineered for this use case. The original code just did int(c) which truncates. Your math.Round + epsilon comparison returns an error for count: 3.5, but silently accepts count: 15 (out of range, falls through to the default). The asymmetry is a bit odd -- if you are going to validate, it would be more consistent to also return an error for out-of-range values rather than silently using the default.

  2. Missing test coverage. This is a behavioral change (string and int types now accepted, non-integer floats rejected). Even a small table-driven test would prevent regressions and document the expected behavior for each type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants